package com.beiding.render;

import java.util.Collection;
import java.util.Map;
import java.util.Set;

//一种特殊类型的上下文
public class This extends RenderContext {


    //向被调用的子模板传入的属性
    private Map<String, String> attributes;

    //所有映射过来的处理器
    private Map<String, String> handlers;

    //是否是根控制器
    private boolean isRoot;

    public This(Map parent, TemplateImpl template, Map<String, String> commands, BoxManager outCreator, Map<String, String> attributes, Map<String, String> handlers, boolean isRoot) {
        super(parent, template, commands, outCreator);
        this.attributes = attributes;
        this.handlers = handlers;
        this.isRoot = isRoot;
    }

    //解析表达式并返回结果
    public Object parse(String expression) {
        return ScriptUtils.parseHolder(this, expression);
    }

    //执行脚本
    public Object execute(String script) {
        return ScriptUtils.exe(this, script);
    }

    public static Object Get(Object key) {
        return currentThisMember.get().get(key);
    }

    public static Object Put(Object key, Object value) {
        return currentThisMember.get().put(key, value);
    }

    public static This current() {
        return currentThisMember.get();
    }

    public static boolean ContainsKey(Object key) {
        return currentThisMember.get().containsKey(key);
    }

    public static Collection Values() {
        return currentThisMember.get().values();
    }

    public static Set KeySet() {
        return currentThisMember.get().keySet();
    }


    public static boolean IsRoot() {
        return currentThisMember.get().isRoot();
    }

    public boolean isRoot() {
        return isRoot;
    }

    public Map<String, String> GetAttributes() {
        return currentThisMember.get().getAttributes();
    }

    public Map<String, String> getAttributes() {
        return attributes;
    }

    public static Map<String, String> GetHandlers() {
        return currentThisMember.get().getHandlers();
    }

    public Map<String, String> getHandlers() {
        return handlers;
    }

    //渲染的结果
    private String result = "";

    public static This Append(Object object) {
        return currentThisMember.get().append(object);
    }

    public This append(Object object) {
        if (object == null) {
            return this;
        }

        if (result == null) {
            result = "";
        }
        result += object;
        return this;
    }


    public static void SetResult(String result) {
        currentThisMember.get().setResult(result);
    }

    public void setResult(String result) {
        this.result = result;
    }

    public static void Render(Map data) {
        currentThisMember.get().render(data);
    }

    public void render(Map data) {
        This _this = new This(this.parent, template, commands, outCreator, attributes, handlers, this.isRoot);
        _this.putAll(data);
        This aThis = currentThisMember.get();
        try {
            currentThisMember.set(_this);
            result = template.innerRender();
        } finally {
            //TODO 处理完归还上下文
            currentThisMember.set(aThis);
        }
    }

    static final ThreadLocal<This> currentThisMember = new ThreadLocal<>();

    public static String Render() {
        return currentThisMember.get().render();
    }

    public String render() {

        This aThis = currentThisMember.get();
        try {
            currentThisMember.set(this);
            result = template.innerRender();
        } finally {
            currentThisMember.set(aThis);
        }
        return result;
    }

    public static String GetResult() {
        return currentThisMember.get().getResult();
    }

    public String getResult() {
        return result;
    }

    public static Box CreateOut(String coordinate) {
        return currentThisMember.get().createOut(coordinate);
    }

    public Box createOut(String coordinate) {
        return outCreator.create(coordinate);
    }

    public static String GetCoordinate() {
        return currentThisMember.get().getCoordinate();
    }

    public String getCoordinate() {
        return template.getCoordinate();
    }


}
